Fix a race condition that causes Emacs to mess up glib.
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 3 Nov 2012 18:32:41 +0000 (11:32 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 3 Nov 2012 18:32:41 +0000 (11:32 -0700)
commit55ffd4962cc72afb14237d439c8e97cdbfd4bf1e
tree2ef790334af58c808799fa3e20a36d0478966b71
parentaa08676d11be87658aba6fb2cac7d2bc93dea18e
Fix a race condition that causes Emacs to mess up glib.

The symptom is a diagnostic "GLib-WARNING **: In call to
g_spawn_sync(), exit status of a child process was requested but
SIGCHLD action was set to SIG_IGN and ECHILD was received by
waitpid(), so exit status can't be returned."  The diagnostic
is partly wrong, as the SIGCHLD action is not set to SIG_IGN.
The real bug is a race condition between Emacs and glib: Emacs
does a waitpid (-1, ...) and reaps glib's subprocess by mistake,
so that glib can't find it.  Work around the bug by invoking
waitpid only on subprocesses that Emacs itself creates.
* process.c (create_process, record_child_status_change):
Don't use special value -1 in pid field, as the caller now must
know the pid rather than having the callee infer it.  The
inference was sometimes incorrect anyway, due to another race.
(create_process): Set new 'alive' member if child is created.
(process_status_retrieved): New function.
(record_child_status_change): Use it.
Accept negative 1st argument, which means to wait for the
processes that Emacs already knows about.  Move special-case code
for DOS_NT (which lacks WNOHANG) here, from caller.  Keep track of
processes that have already been waited for, by testing and
clearing new 'alive' member.
(CAN_HANDLE_MULTIPLE_CHILDREN): Remove, as record_child_status_change
now does this internally.
(handle_child_signal): Let record_child_status_change do all
the work, since we do not want to reap all exited child processes,
only the child processes that Emacs itself created.
* process.h (Lisp_Process): New boolean member 'alive'.
src/ChangeLog
src/process.c
src/process.h